package ee.siimoliver.chat.GUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Window;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import ee.siimoliver.chat.utils.ChatUtils;
/**
 * LoadingFrame for undetermined process done in the background.<br>
 * NB! Start frame with execute() method!
 * @author Siim
 *
 */
public abstract class LoadingFrame extends JFrame implements Runnable {

	public static final long serialVersionUID = 1L;
	protected final int GAP = 10;
	protected final int SPEED = 100;
	protected Window parentFrame;
	protected LoadImage loadImage;
	protected JLabel textLabel;
	protected ArrayList<Image> images;
	protected boolean enableParent;
	
	public LoadingFrame(ArrayList<Image> images, final Window parentFrame) {
		initFrame(images, parentFrame);
		initContent();
		getContentPane().add(loadImage);
		getContentPane().add(textLabel);
		enableParent = true;
	}
	
	public LoadingFrame(ArrayList<Image> images, final Window parentFrame, boolean enableParent) {
		this(images, parentFrame);
		this.enableParent = enableParent;
	}

	private void initContent() {
		textLabel = new JLabel("Loading...");
		textLabel.setFont(new Font(null, Font.BOLD, 16));
		textLabel.setSize(textLabel.getPreferredSize());
		loadImage = new LoadImage();
		int startingWidth = (int) ((this.getWidth() - loadImage.getWidth() - textLabel.getWidth() - GAP) * 0.2);
		loadImage.setLocation(startingWidth, (int) ((this.getHeight() - loadImage.getHeight()) * 0.5));
		textLabel.setLocation(startingWidth + loadImage.getWidth() + GAP, (int) ((this.getHeight() - textLabel.getHeight()) * 0.5));
	}

	private void initFrame(ArrayList<Image> images, final Window parentFrame) {
		this.parentFrame = parentFrame;
		this.images = images;
		setUndecorated(true);
		((JPanel) this.getContentPane()).setBorder(BorderFactory.createLineBorder(Color.BLACK));
		setSize(300, 80);
		ChatUtils.centerWindowRelativeToParent(this, parentFrame);
		setLayout(null);
	}
	
	public void switchLoadingText(String newText) {
		textLabel.setText(newText + "...");
		textLabel.setSize(textLabel.getPreferredSize());
	}

	@Override
	public void run() {
		parentFrame.setEnabled(false);
		setVisible(true);
		loadImage.execute();
		doInBackground();
		loadImage.setRunning(false);
		parentFrame.setEnabled(true);
		if (enableParent) {
			parentFrame.setVisible(true);
		}
		this.dispose();
	}

	protected abstract void doInBackground();
	
	public void execute() {
		new Thread(this).start();
	}
	
	private class LoadImage extends JComponent implements Runnable {

		private static final long serialVersionUID = 1L;
		private int curPic;
		private boolean isRunning;
		
		public LoadImage() {
			setSize(new Dimension(50, 50));
			curPic = 0;
		}
		@Override
		public void paint(Graphics g) {
			g.drawImage(images.get(curPic), 0, 0, null);
		}
		@Override
		public void run() {
			isRunning = true;
			while(isRunning) {
				curPic++;
				if (curPic >= images.size()) {
					curPic = 0;
				}
				repaint();
				try {
					Thread.sleep(SPEED);
				} catch (InterruptedException e) {
				}
			}
		}
		
		public synchronized void setRunning(boolean isRunning) {
			this.isRunning = isRunning;
		}
		public void execute() {
			new Thread(this).start();
		}
	}
	
}
